package org.szy.plugin.sys.service.impl;

import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.query.QueryWrapper;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.ProxyComponent;
import org.noear.solon.data.annotation.Tran;
import org.szy.core.common.enums.CommonStatusEnum;
import org.szy.core.common.service.impl.BaseServiceImpl;
import org.szy.plugin.sys.entity.SysMenu;
import org.szy.plugin.sys.entity.SysRoleMenu;
import org.szy.plugin.sys.mapper.SysRoleMenuMapper;
import org.szy.plugin.sys.service.SysMenuService;
import org.szy.plugin.sys.service.SysRoleMenuService;

import java.util.ArrayList;
import java.util.List;

import static org.szy.plugin.sys.entity.table.SysMenuTableDef.SYS_MENU;
import static org.szy.plugin.sys.entity.table.SysRoleMenuTableDef.SYS_ROLE_MENU;
import static org.szy.plugin.sys.entity.table.SysRoleTableDef.SYS_ROLE;
import static org.szy.plugin.sys.entity.table.SysUserRoleTableDef.SYS_USER_ROLE;

/**
 * 角色菜单关联表
 *
 * @author 孙志阳
 * @date 2023-06-26
 * @since 1.0.0
 **/
@ProxyComponent
public class SysRoleMenuServiceImpl extends BaseServiceImpl<SysRoleMenuMapper, SysRoleMenu> implements SysRoleMenuService {

    @Inject
    private SysMenuService sysMenuService;

    @Override
    public List<SysRoleMenu> listByRoleId(Long roleId) {
        return list(SYS_ROLE_MENU.ROLE_ID.eq(roleId));
    }

    @Override
    @Tran
    public boolean add(SysRoleMenu entity) {
        Long roleId = entity.getRoleId();
        boolean remove = remove(SYS_ROLE_MENU.ROLE_ID.eq(roleId));
        List<String> menuIdList = StrUtil.splitTrim(entity.getMenuId(), ",");

        if (menuIdList.size() > 0) {
            List<SysRoleMenu> list = new ArrayList<>(menuIdList.size());
            menuIdList.forEach(i -> list.add(new SysRoleMenu(roleId, i)));
            return saveBatch(list);
        }
        return remove;
    }

    @Override
    public boolean removeByRolId(Long roleId) {
        return remove(SYS_ROLE_MENU.ROLE_ID.eq(roleId));
    }

    @Override
    public List<SysMenu> listMenuByUserId(String userId) {
        if (StrUtil.isEmpty(userId)) return new ArrayList<>();
        QueryWrapper qw = new QueryWrapper();
        qw.select(SYS_MENU.ID, SYS_MENU.PID, SYS_MENU.NAME, SYS_MENU.TYPE, SYS_MENU.ICON, SYS_MENU.PERMISSION, SYS_MENU.ROUTER, SYS_MENU.APPLICATION, SYS_MENU.SORT)
                .from(SYS_MENU)
                .innerJoin(SYS_ROLE_MENU).on(SYS_MENU.ID.eq(SYS_ROLE_MENU.MENU_ID))
                .innerJoin(SYS_USER_ROLE).on(SYS_ROLE_MENU.ROLE_ID.eq(SYS_USER_ROLE.ROLE_ID))
                .innerJoin(SYS_ROLE).on(SYS_ROLE.ID.eq(SYS_ROLE_MENU.ROLE_ID))
                .and(SYS_MENU.STATUS.eq(CommonStatusEnum.ENABLE.getKey()))
                .and(SYS_MENU.TYPE.in(0, 1))
                .and(SYS_ROLE.STATUS.eq(CommonStatusEnum.ENABLE.getKey()))
                .and(SYS_USER_ROLE.USER_ID.eq(userId))
                .and(SYS_USER_ROLE.USER_ID.isNotNull()).and(SYS_USER_ROLE.USER_ID.ne(StrUtil.EMPTY))
                .orderBy(SYS_MENU.SORT.asc());
        return sysMenuService.list(qw);
    }

    @Override
    public List<SysMenu> listMenuByRoleCode(String roleCodes) {
        if (StrUtil.isEmpty(roleCodes)) return new ArrayList<>();
        List<String> codes = StrUtil.splitTrim(roleCodes, ",");
        QueryWrapper qw = new QueryWrapper();
        qw.select(SYS_MENU.ID, SYS_MENU.PID, SYS_MENU.NAME, SYS_MENU.TYPE, SYS_MENU.ICON, SYS_MENU.PERMISSION, SYS_MENU.ROUTER, SYS_MENU.APPLICATION, SYS_MENU.SORT)
                .from(SYS_MENU)
                .innerJoin(SYS_ROLE_MENU).on(SYS_MENU.ID.eq(SYS_ROLE_MENU.MENU_ID))
                .innerJoin(SYS_ROLE).on(SYS_ROLE.ID.eq(SYS_ROLE_MENU.ROLE_ID))
                .and(SYS_MENU.STATUS.eq(CommonStatusEnum.ENABLE.getKey()))
                .and(SYS_MENU.TYPE.in(0, 1))
                .and(SYS_ROLE.STATUS.eq(CommonStatusEnum.ENABLE.getKey()))
                .and(SYS_ROLE.CODE.in(codes))
                .and(SYS_ROLE.CODE.isNotNull()).and(SYS_ROLE.CODE.ne(StrUtil.EMPTY))
                .orderBy(SYS_MENU.SORT.asc());
        ;
        return sysMenuService.list(qw);
    }
}
